package com.fruit.system.listener;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;
import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;

import com.fruit.auth.model.Department;
import com.fruit.auth.model.Privilege;
import com.fruit.auth.model.Role;
import com.fruit.auth.model.User;
import com.fruit.auth.model.UserRole;
import com.fruit.auth.service.DepartmentService;
import com.fruit.auth.service.PrivilegeService;
import com.fruit.auth.service.RoleService;
import com.fruit.auth.service.UserService;
import com.fruit.system.model.Menu;
import com.fruit.system.service.LogService;
import com.fruit.system.service.MenuService;
import com.fruit.util.LogUtil;
@Component
public class SytemInitListener  implements ApplicationListener<ContextRefreshedEvent>,ServletContextAware
{
	private boolean isStarted=false;
	private ServletContext servletContext;
	private final Logger logger=LoggerFactory.getLogger(this.getClass());
	
	@Resource(name="userService")
	private UserService userService;
	
	@Resource(name="roleService")
	private RoleService roleService;
	
	@Resource(name="logService")
	private LogService logService;
	
	@Resource(name="menuService")
	private MenuService menuService;
	
	@Resource(name="departmentService")
	private DepartmentService departmentService;
	
	@Resource(name="privilegeService")
	private PrivilegeService privilegeService;
	
	@Override
	public void onApplicationEvent(ContextRefreshedEvent event)
	{
		/*如果不加这句话，会调用2次，因为在web 项目中，
		 * 系统会存在两个容器一次是root application context ,
		 * 另一个就是我们自己的 projectName-servlet context（作为root application context的子容器）。
		*applicationontext和使用MVC之后的webApplicationontext会两次调用上面的方法
		*这种情况下，就会造成onApplicationEvent方法被执行两次。
		*为了避免上面提到的问题，我们可以只在root application context初始化完成后调用逻辑代码，
		*其他的容器的初始化完成，则不做任何处理，修改后代码
		**/
		if(isStarted) return;
		//初始化数据库
		Properties prop=new Properties();
		URL fileURL=null;
		File systemPropertyFile=null;
		try
		{
			fileURL=this.getClass().getClassLoader().getResource("system.properties");
			systemPropertyFile=new File(fileURL.toURI());
			FileInputStream in=new FileInputStream(systemPropertyFile);
			prop.load(in);
			in.close();
		}
		catch(URISyntaxException e)
		{
			throw new RuntimeException("file path error:system.properties");
		}
		catch (IOException e)
		{
			throw new RuntimeException("can't find the file:system.properties");
		}
		if(prop.getProperty("initDatabase").equals("true"))
		{
			logger.info("正在进行系统初始化，请稍候...");
			//初始化日志表
			String sql="create table if not exists "+LogUtil.generateLogTableName(0)+" like logs";
			logService.executeUpdateSql(sql);
			sql="create table if not exists "+LogUtil.generateLogTableName(1)+" like logs";
			logService.executeUpdateSql(sql);
			sql="create table if not exists "+LogUtil.generateLogTableName(2)+" like logs";
			logService.executeUpdateSql(sql);
			logger.info("日志表初始化完成...");
			
			//初始化用户
			User user=new User();
			//初始化部门
			Department department=new Department();
			department.setDescription("总公司");
			department.setLeaf(false);
			department.setName("总部");
			department.setPhone("027-5736455");
			
			Department department1=new Department();
			department1.setDescription("技术部门，技术宅");
			department1.setName("技术部");
			department1.setPhone("027-5736988");
			department1.setLeaf(true);
			department1.setParent(department);
			logger.info("部门表初始化完成...");
			
			
			
			user.setUsername("admin");
			user.setPassword("123456");
			user.setNickname("张三");
			user.setDepartment(department1);
			
			departmentService.saveEntity(department);
			departmentService.saveEntity(department1);
			
			userService.saveUser(user);
			
			logger.info("用户表初始化完成...");
			
			
			
			
			//初始化角色
			Role role=new Role();
			role.setName("超级管理员");
			role.setDescription("具有一切权限");
			role.setRoleCode("ROLE_ADMIN");
			
			roleService.saveEntity(role);
			UserRole ur=new UserRole();
			ur.setUser(user);
			ur.setRole(role);
			userService.saveUserRole(ur);
			logger.info("角色表初始化完成...");
			
			
			//初始化菜单
			Menu menu=new Menu();
			menu.setIsLeaf(false);
			menu.setName("系统管理");
			menu.setDescription("顶级菜单-系统管理");
			
			Menu menu1=new Menu();
			menu1.setName("用户管理");
			menu1.setDescription("顶级菜单-用户管理");
			menu1.setParent(menu);
			
			Menu menu2=new Menu();
			menu2.setName("部门管理");
			menu2.setDescription("顶级菜单-部门管理");
			menu2.setParent(menu);
			menu2.setUrl("/securityJsp/auth/department.jsp");
			
			Menu menu3=new Menu();
			menu3.setName("角色管理");
			menu3.setDescription("顶级菜单-角色管理");
			menu3.setParent(menu);
			menu3.setUrl("/securityJsp/auth/role.jsp");
			Menu menu4=new Menu();
			menu4.setName("权限管理");
			menu4.setDescription("顶级菜单-权限管理");
			menu4.setUrl("/securityJsp/auth/privilege.jsp");
			menu4.setParent(menu);
			
			Menu menu5=new Menu();
			menu5.setName("菜单管理");
			menu5.setDescription("顶级菜单-菜单管理");
			
			Menu menu6=new Menu();
			menu6.setName("商品管理");
			menu6.setDescription("商品管理");
			
			Menu menu7=new Menu();
			menu7.setName("商品分类");
			menu7.setDescription("商品分类");
			menu7.setParent(menu6);
			
			Menu menu8=new Menu();
			menu8.setName("出售中的商品");
			menu8.setDescription("出售中的商品");
			menu8.setParent(menu6);
			
			
			Menu menu9=new Menu();
			menu9.setName("未上架的商品");
			menu9.setDescription("未上架的商品");
			menu9.setParent(menu6);
			
			Menu menu10=new Menu();
			menu10.setName("订单管理");
			menu10.setDescription("订单管里");
			menu10.setParent(menu6);
			
			menuService.saveMenu(menu);
			
			menuService.saveMenu(menu1);
			menuService.saveMenu(menu2);
			menuService.saveMenu(menu3);
			menuService.saveMenu(menu4);
			menuService.saveMenu(menu5);
			menuService.saveMenu(menu6);
			menuService.saveMenu(menu7);
			menuService.saveMenu(menu8);
			menuService.saveMenu(menu9);
			menuService.saveMenu(menu10);
			logger.info("菜单表初始化完成...");
			
			//权限初始化
			
			
			prop.setProperty("initDatabase", "false");
			try
			{
				FileOutputStream out=new FileOutputStream(systemPropertyFile);
				prop.store(out,"是否初始化系统数据库");
				out.close();
			}
			catch (FileNotFoundException e)
			{
				e.printStackTrace();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			logger.info("系统数据库初始化完毕...");
		}
		isStarted=true;
		
		List<Privilege> privileges=privilegeService.findAllPrivileges();
		Map<String,Privilege> privilegeMap=new HashMap<String,Privilege>();
		for(Privilege p:privileges)
			privilegeMap.put(p.getUrl(), p);
		servletContext.setAttribute("allPrivileges", privilegeMap);
	}

	@Override
	public void setServletContext(ServletContext servletContext)
	{
		this.servletContext=servletContext;
	}

}
